package sv.view;

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import sv.main.*;

public class MouseFieldAdapter extends MouseAdapter {

	private boolean horizontalAlignment = true;

	private Game game;

	private byte shipsToSet;

	private JTextArea log;
	
	private View gui;
	
	private MyNetwork connection;

	public MouseFieldAdapter(Game game, JTextArea log, View gui, MyNetwork con) {
		this.game = game;
		shipsToSet = 5;
		this.log = log;
		this.gui = gui;
		connection = con;
	}

	public void mouseEntered(MouseEvent event) {
		JPanel source = (JPanel) event.getSource();
		JPanel board = (JPanel) source.getParent();
		int x = source.getX() / 20;
		int y = source.getY() / 20;
		byte freeSpaces = 5;

		setShip(shipsToSet, freeSpaces, x, y, board, source);
	}

	public void mousePressed(MouseEvent event) {
		byte pseudoShips = 0;
		JPanel source = (JPanel) event.getSource();

		if (event.isMetaDown()) {
			horizontalAlignment = !horizontalAlignment;
			mouseEntered(event);
		} else {
			for (byte i = 0; i < 10; i++) {
				for (byte j = 0; j < 10; j++) {
					if (game.getTile(i, j) == Game.State.PSEUDOSHIP) {
						pseudoShips++;
					}
				}
			}
			if (((shipsToSet>2) && (pseudoShips == shipsToSet)) || ((shipsToSet<3) && (pseudoShips-1 == shipsToSet))) {
				for (byte i = 0; i < 10; i++) {
					for (byte j = 0; j < 10; j++) {
						if (game.getTile(i, j) == Game.State.PSEUDOSHIP) {
							game.changeTile(i, j, Game.State.SHIP);
							game.setShipId(i, j, shipsToSet);
						}
					}
				}
				if (shipsToSet > 1) {
					shipsToSet--;
				}
				else {
					shipsToSet--;
					log.append("all ships deployed\n");
					gui.enableBattleAdapter();
					if (game.isOppReady()){
						log.append("all players ready\n");
						log.append("let the battle begin...\n");
						game.setAllReady(true);
					}
					connection.connection().sendReady();
					game.setSelfReady(true);
				}
			} else {
				log.append("illegal ship position\n");
			}
		}
	}

	public void setShip(byte n, byte freeSpaces, int x, int y, JPanel board,
			JPanel source) {
		int rawX = x * 20;
		int rawY = y * 20;

		for (byte i = 0; i < 10; i++) {
			for (byte j = 0; j < 10; j++) {
				if (game.getTile(i, j) != Game.State.SHIP) {
					changeTileToWater(i, j, board);
				}
			}
		}

		switch (n) {
		case 5:
			if (horizontalAlignment) {

				if (board.getComponentAt(rawX + 80, rawY) == null) {
					if (board.getComponentAt(rawX + 60, rawY) == null) {
						if (board.getComponentAt(rawX + 40, rawY) == null) {
							if (board.getComponentAt(rawX + 20, rawY) == null) {
								freeSpaces = 0;
							} else
								freeSpaces = 1;
						} else
							freeSpaces = 2;
					} else
						freeSpaces = 3;
				} else
					freeSpaces = 4;

				changeTileToShip(x, y, board);
				switch (freeSpaces) {
				case 4:
					changeTileToShip(x + 1, y, board);
					changeTileToShip(x + 2, y, board);
					changeTileToShip(x + 3, y, board);
					changeTileToShip(x + 4, y, board);
					break;

				case 3:
					changeTileToShip(x + 1, y, board);
					changeTileToShip(x + 2, y, board);
					changeTileToShip(x + 3, y, board);
					changeTileToShip(x - 1, y, board);
					break;

				case 2:
					changeTileToShip(x + 1, y, board);
					changeTileToShip(x + 2, y, board);
					changeTileToShip(x - 1, y, board);
					changeTileToShip(x - 2, y, board);
					break;

				case 1:
					changeTileToShip(x + 1, y, board);
					changeTileToShip(x - 1, y, board);
					changeTileToShip(x - 2, y, board);
					changeTileToShip(x - 3, y, board);
					break;

				case 0:
					changeTileToShip(x - 1, y, board);
					changeTileToShip(x - 2, y, board);
					changeTileToShip(x - 3, y, board);
					changeTileToShip(x - 4, y, board);
				}
			} else {
				if (board.getComponentAt(rawX, rawY + 80) == null) {
					if (board.getComponentAt(rawX, rawY + 60) == null) {
						if (board.getComponentAt(rawX, rawY + 40) == null) {
							if (board.getComponentAt(rawX, rawY + 20) == null) {
								freeSpaces = 0;
							} else
								freeSpaces = 1;
						} else
							freeSpaces = 2;
					} else
						freeSpaces = 3;
				} else
					freeSpaces = 4;

				changeTileToShip(x, y, board);
				switch (freeSpaces) {
				case 4:
					changeTileToShip(x, y + 1, board);
					changeTileToShip(x, y + 2, board);
					changeTileToShip(x, y + 3, board);
					changeTileToShip(x, y + 4, board);
					break;

				case 3:
					changeTileToShip(x, y + 1, board);
					changeTileToShip(x, y + 2, board);
					changeTileToShip(x, y + 3, board);
					changeTileToShip(x, y - 1, board);
					break;

				case 2:
					changeTileToShip(x, y + 1, board);
					changeTileToShip(x, y + 2, board);
					changeTileToShip(x, y - 1, board);
					changeTileToShip(x, y - 2, board);
					break;

				case 1:
					changeTileToShip(x, y + 1, board);
					changeTileToShip(x, y - 1, board);
					changeTileToShip(x, y - 2, board);
					changeTileToShip(x, y - 3, board);
					break;

				case 0:
					changeTileToShip(x, y - 1, board);
					changeTileToShip(x, y - 2, board);
					changeTileToShip(x, y - 3, board);
					changeTileToShip(x, y - 4, board);
					break;
				}
			}
			break;
		case 4:
			if (horizontalAlignment) {

				if (board.getComponentAt(rawX + 60, rawY) == null) {
					if (board.getComponentAt(rawX + 40, rawY) == null) {
						if (board.getComponentAt(rawX + 20, rawY) == null) {
							freeSpaces = 0;
						} else
							freeSpaces = 1;
					} else
						freeSpaces = 2;
				} else
					freeSpaces = 3;

				changeTileToShip(x, y, board);
				switch (freeSpaces) {
				case 3:
					changeTileToShip(x + 1, y, board);
					changeTileToShip(x + 2, y, board);
					changeTileToShip(x + 3, y, board);
					break;

				case 2:
					changeTileToShip(x + 1, y, board);
					changeTileToShip(x + 2, y, board);
					changeTileToShip(x - 1, y, board);
					break;

				case 1:
					changeTileToShip(x + 1, y, board);
					changeTileToShip(x - 1, y, board);
					changeTileToShip(x - 2, y, board);
					break;

				case 0:
					changeTileToShip(x - 1, y, board);
					changeTileToShip(x - 2, y, board);
					changeTileToShip(x - 3, y, board);
				}
			} else {
				if (board.getComponentAt(rawX, rawY + 60) == null) {
					if (board.getComponentAt(rawX, rawY + 40) == null) {
						if (board.getComponentAt(rawX, rawY + 20) == null) {
							freeSpaces = 0;
						} else
							freeSpaces = 1;
					} else
						freeSpaces = 2;
				} else
					freeSpaces = 3;

				changeTileToShip(x, y, board);
				switch (freeSpaces) {

				case 3:
					changeTileToShip(x, y + 1, board);
					changeTileToShip(x, y + 2, board);
					changeTileToShip(x, y + 3, board);
					break;

				case 2:
					changeTileToShip(x, y + 1, board);
					changeTileToShip(x, y + 2, board);
					changeTileToShip(x, y - 1, board);
					break;

				case 1:
					changeTileToShip(x, y + 1, board);
					changeTileToShip(x, y - 1, board);
					changeTileToShip(x, y - 2, board);
					break;

				case 0:
					changeTileToShip(x, y - 1, board);
					changeTileToShip(x, y - 2, board);
					changeTileToShip(x, y - 3, board);
					break;
				}
			}
			break;
		case 3:
		case 2:
			if (horizontalAlignment) {

				if (board.getComponentAt(rawX + 40, rawY) == null) {
					if (board.getComponentAt(rawX + 20, rawY) == null) {
						freeSpaces = 0;
					} else
						freeSpaces = 1;
				} else
					freeSpaces = 2;

				changeTileToShip(x, y, board);
				switch (freeSpaces) {

				case 2:
					changeTileToShip(x + 1, y, board);
					changeTileToShip(x + 2, y, board);
					break;

				case 1:
					changeTileToShip(x + 1, y, board);
					changeTileToShip(x - 1, y, board);
					break;

				case 0:
					changeTileToShip(x - 1, y, board);
					changeTileToShip(x - 2, y, board);
				}
			} else {
				if (board.getComponentAt(rawX, rawY + 40) == null) {
					if (board.getComponentAt(rawX, rawY + 20) == null) {
						freeSpaces = 0;
					} else
						freeSpaces = 1;
				} else
					freeSpaces = 2;

				changeTileToShip(x, y, board);
				switch (freeSpaces) {

				case 2:
					changeTileToShip(x, y + 1, board);
					changeTileToShip(x, y + 2, board);
					break;

				case 1:
					changeTileToShip(x, y + 1, board);
					changeTileToShip(x, y - 1, board);
					break;

				case 0:
					changeTileToShip(x, y - 1, board);
					changeTileToShip(x, y - 2, board);
					break;
				}
			}
			break;
		case 1:
			if (horizontalAlignment) {

				if (board.getComponentAt(rawX + 20, rawY) == null) {
					freeSpaces = 0;
				} else
					freeSpaces = 1;

				changeTileToShip(x, y, board);
				switch (freeSpaces) {

				case 1:
					changeTileToShip(x + 1, y, board);
					break;

				case 0:
					changeTileToShip(x - 1, y, board);
				}
			} else {
				if (board.getComponentAt(rawX, rawY + 20) == null) {
					freeSpaces = 0;
				} else
					freeSpaces = 1;

				changeTileToShip(x, y, board);
				switch (freeSpaces) {

				case 1:
					changeTileToShip(x, y + 1, board);
					break;

				case 0:
					changeTileToShip(x, y - 1, board);
					break;
				}
			}
			break;
		}
	}

	public void changeTileToShip(int x, int y, JPanel board) {
		if (game.getTile(x, y) != Game.State.SHIP) {
			board.getComponentAt(x * 20, y * 20).setBackground(Color.green);
			game.changeTile(x, y, Game.State.PSEUDOSHIP);
		}
	}

	public void changeTileToWater(int x, int y, JPanel board) {
		board.getComponentAt(x * 20, y * 20).setBackground(Color.blue);
		game.changeTile(x, y, Game.State.WATER);
	}

}
